#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <getopt.h>
#include <linux/kvm.h>
 
#define KVM_FILE "/dev/kvm"

#define KVM_START_TRACE       _IOWR(KVMIO, 0xE0, struct trace_control)
#define KVM_STOP_TRACE       _IOWR(KVMIO, 0xE1, struct trace_control)

struct trace_control {
        char vm_ts[256];
        char tag[256];
        char ret[256];
};

char* const short_options = "h";
struct option long_options[] = {
		{ "vm",     1,   NULL,    'v'     },
		{ "tag",  1,   NULL,    't'     },
		{      0,     0,     0,     0},
};
 
int main(int argc, char * argv[])
{
	int dev;
	int ret;
	int opt = 0;
	struct trace_control trace_control;
	strcpy(trace_control.vm_ts, "11111.11111");
	strcpy(trace_control.tag, "crumbs");
	strcpy(trace_control.ret, "Fail to start trace, maybe kvm is not running");
	while ((opt = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
	{
		switch(opt)
		{
		case 'v':
			strcpy(trace_control.vm_ts, optarg);
			printf("vm ts is %s\n", optarg);
			break;
		case 't':
			strcpy(trace_control.tag, optarg);
			printf("trace tag is %s\n", optarg);
			break;
		case 'h':
			printf("./program --vm [] --tag []\n");
			break;
		case '?':
			/* Case when user enters the command as
			 * $ ./cmd_exe -v
			 */
			if (optopt == 'v') {
				printf("\nMissing mandatory vm ts option");
				/* Case when user enters the command as
				 * # ./cmd_exe -t
				 */
			} else if (optopt == 't') {
				printf("\nMissing mandatory trace tag option");
			} else {
				printf("\nInvalid option received");
			}
			exit(1);
			break;
		}
	}
 
	dev = open(KVM_FILE,O_RDWR|O_NDELAY);
	ret = ioctl(dev, KVM_START_TRACE, &trace_control);
	printf("return: %s\n", trace_control.ret);
	return 0;
}
